"""
多因素MACD策略使用示例
包含基础功能测试、参数优化演示和真实数据加载说明
"""

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
import os
# 支持中文
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

# 导入策略类和优化器
from macd_multi_factor_strategy import MultiFactorMACDStrategy
from parameter_optimizer import ParameterOptimizer

# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.style.use('seaborn-v0_8')


def create_sample_data(start_date='2023-01-01', end_date='2023-12-31', seed=42):
    """创建示例股票数据"""
    dates = pd.date_range(start_date, end_date, freq='D')
    np.random.seed(seed)
    
    # 生成带趋势的价格数据
    trend = np.linspace(100, 130, len(dates))
    noise = np.random.randn(len(dates)) * 2
    price = trend + np.cumsum(noise) * 0.4
    price = np.maximum(price, 1)  # 确保价格为正
    
    # 生成其他字段
    df = pd.DataFrame({
        '日期': dates,
        '股票代码': '000001.SZ',
        '开盘': price * (1 - np.random.uniform(0, 0.02, len(dates))),
        '收盘': price,
        '最高': price * (1 + np.random.uniform(0, 0.03, len(dates))),
        '最低': price * (1 - np.random.uniform(0, 0.03, len(dates))),
        '成交量': np.random.randint(1000000, 8000000, len(dates)),
        '成交额': price * np.random.randint(1000000, 8000000, len(dates)),
        '振幅': np.random.uniform(1, 6, len(dates)),
        '涨跌幅': np.random.uniform(-4, 4, len(dates)),
        '涨跌额': np.random.uniform(-3, 3, len(dates)),
        '换手率': np.random.uniform(0.8, 4, len(dates))
    })
    
    return df


def test_basic_functionality():
    """测试策略的基本功能"""
    print("=" * 50)
    print("测试策略基本功能")
    print("=" * 50)
    
    # 创建示例数据
    df = create_sample_data()
    print(f"生成示例数据: {len(df)} 行")
    
    # 创建策略实例
    strategy = MultiFactorMACDStrategy(
        fast_period=12,
        slow_period=26,
        signal_period=9,
        rsi_period=14,
        rsi_low_threshold=30,
        rsi_high_threshold=70,
        ma_short_period=5,
        ma_long_period=20,
        atr_period=14,
        stop_loss_multiplier=2.0,
        take_profit_multiplier=3.0
    )
    
    print("\n1. 测试技术指标计算功能:")
    # 计算MACD指标
    df_with_macd = strategy.calculate_macd(df)
    print(f"   - MACD指标计算完成: {sum(df_with_macd['MACD'].notna())} 个有效值")
    
    # 计算RSI指标
    df_with_rsi = strategy.calculate_rsi(df_with_macd)
    print(f"   - RSI指标计算完成: {sum(df_with_rsi['RSI'].notna())} 个有效值")
    
    # 计算双均线交叉
    df_with_ma = strategy.calculate_ma_cross(df_with_rsi)
    print(f"   - 双均线指标计算完成: {sum(df_with_ma['MA_Short'].notna())} 个短期均线值, {sum(df_with_ma['MA_Long'].notna())} 个长期均线值")
    
    # 计算ATR指标
    df_with_atr = strategy.calculate_atr(df_with_ma)
    print(f"   - ATR指标计算完成: {sum(df_with_atr['ATR'].notna())} 个有效值")
    
    # 计算成交量过滤
    df_with_volume = strategy.calculate_volume_filter(df_with_atr)
    print(f"   - 成交量过滤计算完成: {sum(df_with_volume['Volume_Filter'] > 0)} 个成交量放大信号")
    
    print("\n2. 测试交易信号生成功能:")
    # 生成交易信号
    df_with_signals = strategy.generate_signals(df_with_volume)
    
    # 统计信号数量
    buy_signals = sum(df_with_signals['Signal'] == 1)
    sell_signals = sum(df_with_signals['Signal'] == -1)
    print(f"   - 买入信号数量: {buy_signals}")
    print(f"   - 卖出信号数量: {sell_signals}")
    
    # 验证信号分布
    if buy_signals > 0 and sell_signals > 0:
        print("   - 信号生成验证通过: 成功生成买入和卖出信号")
    else:
        print("   - 信号生成验证警告: 信号数量异常")
    
    print("\n3. 测试回测功能:")
    # 执行回测
    results = strategy.backtest_strategy(df_with_signals, initial_capital=100000)
    
    # 输出回测结果摘要
    print(f"   - 初始资金: {results['initial_capital']:,.2f}")
    print(f"   - 最终资金: {results['final_capital']:,.2f}")
    print(f"   - 总收益率: {results['total_return']:.2f}%")
    print(f"   - 最大回撤: {results['max_drawdown']:.2f}%")
    print(f"   - 交易次数: {results['trade_count']}")
    print(f"   - 胜率: {results['win_rate']:.2f}%")
    
    # 验证回测结果
    if results['final_capital'] > 0:
        print("   - 回测功能验证通过: 成功完成策略回测")
    else:
        print("   - 回测功能验证失败: 回测结果异常")
    
    print("\n4. 测试可视化功能:")
    try:
        # 生成可视化图表
        strategy.plot_results(df_with_signals, results)
        print("   - 可视化功能验证通过: 成功生成回测结果图表")
    except Exception as e:
        print(f"   - 可视化功能验证失败: {e}")
    
    print("\n5. 测试交易记录导出功能:")
    try:
        # 导出交易记录
        strategy.export_trade_records(results, 'example_trade_records.csv')
        if os.path.exists('example_trade_records.csv'):
            print(f"   - 交易记录导出验证通过: 成功导出到 example_trade_records.csv")
            # 读取并显示前5行
            trade_df = pd.read_csv('example_trade_records.csv')
            print(f"   - 交易记录共 {len(trade_df)} 行")
            if len(trade_df) > 0:
                print("   - 交易记录前3行:")
                print(trade_df.head(3).to_string(index=False))
        else:
            print("   - 交易记录导出验证失败: 文件未生成")
    except Exception as e:
        print(f"   - 交易记录导出验证失败: {e}")
    
    print("\n" + "=" * 50)
    print("基本功能测试完成")
    print("=" * 50)
    
    return df_with_signals, results


def demonstrate_parameter_optimization():
    """演示参数优化功能"""
    print("\n" + "=" * 50)
    print("演示参数优化功能")
    print("=" * 50)
    
    # 创建示例数据
    df = create_sample_data()
    print(f"生成优化测试数据: {len(df)} 行")
    
    # 创建优化器实例
    optimizer = ParameterOptimizer(MultiFactorMACDStrategy, initial_capital=100000)
    
    # 创建简单的参数网格（快速测试）
    print("创建参数网格 (简单复杂度)...")
    param_grid = optimizer.create_parameter_grid(complexity='simple')
    print(f"参数组合数量: {optimizer.calculate_combination_count(param_grid)}")
    
    # 运行网格搜索
    print("运行参数优化 (这可能需要几分钟时间)...")
    try:
        best_params, best_performance, all_results = optimizer.run_grid_search(
            df, param_grid, performance_metric='sharpe_ratio', 
            use_progress_bar=True, save_results=True
        )
        
        print("\n参数优化结果:")
        print(f"最佳参数组合: {best_params}")
        print(f"最佳夏普比率: {best_performance:.4f}")
        
        # 可视化优化结果（可选）
        # optimizer.visualize_optimization_results(top_n=3)
        
        # 分析参数敏感性（可选）
        # if 'fast_period' in best_params:
        #     optimizer.analyze_parameter_sensitivity('fast_period')
        
        print("\n参数优化功能演示完成")
        return best_params, best_performance
    except Exception as e:
        print(f"参数优化演示失败: {e}")
        return None, None


def load_and_analyze_real_data(file_path=None):
    """加载和分析真实股票数据"""
    print("\n" + "=" * 50)
    print("加载和分析真实股票数据")
    print("=" * 50)
    
    if file_path is None:
        print("提示: 请提供真实股票数据文件路径")
        print("数据格式要求:")
        print("- 必须包含以下字段: ['日期', '股票代码', '开盘', '收盘', '最高', '最低', '成交量', '成交额', '振幅', '涨跌幅', '涨跌额', '换手率']")
        print("- 日期字段应为日期类型")
        print("- 价格和成交量字段应为数值类型")
        print("\n示例代码:")
        print("# 加载CSV数据")
        print("df = pd.read_csv('your_stock_data.csv')")
        print("# 转换日期字段")
        print("df['日期'] = pd.to_datetime(df['日期'])")
        print("# 排序数据")
        print("df = df.sort_values('日期')")
        print("# 重置索引")
        print("df = df.reset_index(drop=True)")
        return None
    
    try:
        # 加载数据
        print(f"正在加载数据: {file_path}")
        df = pd.read_csv(file_path)
        
        # 检查必要字段
        required_columns = ['日期', '股票代码', '开盘', '收盘', '最高', '最低', '成交量', '成交额', '振幅', '涨跌幅', '涨跌额', '换手率']
        missing_columns = [col for col in required_columns if col not in df.columns]
        
        if missing_columns:
            print(f"错误: 缺少必要字段: {missing_columns}")
            return None
        
        # 转换日期字段
        df['日期'] = pd.to_datetime(df['日期'])
        
        # 排序数据
        df = df.sort_values('日期')
        df = df.reset_index(drop=True)
        
        print(f"数据加载完成: {len(df)} 行, 时间范围: {df['日期'].min().date()} 至 {df['日期'].max().date()}")
        
        # 数据统计
        print("\n数据统计摘要:")
        print(f"收盘价范围: {df['收盘'].min():.2f} - {df['收盘'].max():.2f}")
        print(f"平均成交量: {df['成交量'].mean():,.0f}")
        print(f"平均涨跌幅: {df['涨跌幅'].mean():.2f}%")
        
        # 显示前5行
        print("\n数据前3行:")
        print(df.head(3).to_string(index=False))
        
        return df
    except Exception as e:
        print(f"数据加载失败: {e}")
        return None


def run_strategy_with_best_params(df, best_params, initial_capital=100000):
    """使用最佳参数运行策略"""
    if best_params is None:
        print("警告: 未提供最佳参数，使用默认参数")
        best_params = {}
    
    print(f"\n使用最佳参数运行策略: {best_params}")
    
    # 创建策略实例
    strategy = MultiFactorMACDStrategy(**best_params)
    
    # 计算指标
    df_with_indicators = df.copy()
    df_with_indicators = strategy.calculate_macd(df_with_indicators)
    df_with_indicators = strategy.calculate_rsi(df_with_indicators)
    df_with_indicators = strategy.calculate_ma_cross(df_with_indicators)
    df_with_indicators = strategy.calculate_atr(df_with_indicators)
    df_with_indicators = strategy.calculate_volume_filter(df_with_indicators)
    
    # 生成信号
    df_with_signals = strategy.generate_signals(df_with_indicators)
    
    # 执行回测
    results = strategy.backtest_strategy(df_with_signals, initial_capital)
    
    # 可视化结果
    strategy.plot_results(df_with_signals, results, save_path='best_params_results.png')
    
    # 导出交易记录
    strategy.export_trade_records(results, 'best_params_trade_records.csv')
    
    return results


def main():
    """主函数"""
    print("多因素MACD策略使用示例")
    print("=" * 50)
    
    # 步骤1: 测试基本功能
    print("\n步骤1: 测试策略基本功能")
    df_with_signals, basic_results = test_basic_functionality()
    
    # 步骤2: 演示参数优化
    print("\n步骤2: 演示参数优化功能")
    # 注意：对于快速测试，您可以注释掉这一行以节省时间
    best_params, best_performance = demonstrate_parameter_optimization()
    
    # 步骤3: 加载真实数据（可选）
    print("\n步骤3: 加载和分析真实股票数据 (可选)")
    # 取消注释并提供文件路径以加载真实数据
    # real_df = load_and_analyze_real_data('your_stock_data.csv')
    
    # 步骤4: 使用最佳参数运行策略（可选）
    print("\n步骤4: 使用最佳参数运行策略 (可选)")
    # 如果加载了真实数据并且有最佳参数，可以运行以下代码
    # if real_df is not None and best_params is not None:
    #     best_results = run_strategy_with_best_params(real_df, best_params)
    
    print("\n" + "=" * 50)
    print("使用示例运行完成")
    print("提示:")
    print("1. 查看生成的图表以分析策略性能")
    print("2. 检查导出的交易记录文件以了解详细交易情况")
    print("3. 尝试调整参数以优化策略性能")
    print("4. 使用真实数据进行更准确的回测")
    print("=" * 50)

if __name__ == "__main__":
    main()